/**
 * <copyright> 
 *
 * Copyright (c) 2008 itemis AG and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 *   itemis AG - Initial API and implementation
 *
 * </copyright>
 *
 */
package com.rd.emf.geneditor.view.editors.generic.binding;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.forms.widgets.FormToolkit;

/**
 * @author Dennis Huebner
 * 
 */
public class MultipleFeatureControl extends Composite {

//	private FeatureEditorDialog dialog;
	private Collection<?> currentValue;
	private final ILabelProvider labelProvider;
	private ISelectionProvider inernalProvider = new InternalSelectionProvider();

	private Label label;

	private Table table;
	private CheckboxTableViewer checkboxTableViewer;

	// private IPropertyChangeListener propertyChangeListener;
	private boolean beQueit;

	public MultipleFeatureControl(final Composite parent, FormToolkit toolkit,
			final ILabelProvider labelProvider, final Object object,
			final EStructuralFeature feature,
			final List<? extends Object> choiceOfValues) {
		super(parent, SWT.NONE);
		this.labelProvider = labelProvider;
		toolkit.adapt(this);
		setLayout(new GridLayout(2, false));
		label = toolkit.createLabel(this, "");
		label.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				MultipleFeatureControl.this.setFocus();
			}
		});
		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		checkboxTableViewer = CheckboxTableViewer.newCheckList(this, SWT.BORDER);
        table = checkboxTableViewer.getTable();
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        checkboxTableViewer.setContentProvider(new ArrayContentProvider());
        checkboxTableViewer.setLabelProvider(new ITableLabelProvider() {

		    @Override
		    public Image getColumnImage(Object element, int columnIndex) {
			return null;
		    }

		    @Override
		    public String getColumnText(Object element, int columnIndex) {
		    	return (String) element;
		    }

		    @Override
		    public void dispose() {

		    }

		    @Override
		    public boolean isLabelProperty(Object element,
			    String property) {
			return false;
		    }

			@Override
			public void addListener(ILabelProviderListener listener) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void removeListener(ILabelProviderListener listener) {
				// TODO Auto-generated method stub
				
			}
		});

//		button = toolkit.createButton(this, "...", SWT.PUSH);
//		button.setLayoutData(new GridData());
//		button.addSelectionListener(new SelectionAdapter() {
//
//			@Override
//			public void widgetSelected(SelectionEvent e) {
//				List<?> oldValue = unwrapSelection();
//				dialog = new FeatureEditorDialog(parent.getShell(),
//						labelProvider, object, feature.getEType(), oldValue,
//						"Display Name", choiceOfValues, false, feature
//								.isOrdered());
//				dialog.setBlockOnOpen(true);
//				if (dialog.open() == Window.OK) {
//					setSelection(new StructuredSelection(dialog.getResult()
//							.toArray()));
//					// propertyChangeListener
//					// .propertyChange(new PropertyChangeEvent(this,
//					// feature.getName(), oldValue, currentValue));
//				}
//			}
//		});

	}

	protected void setSelection(ISelection structuredSelection) {
		this.inernalProvider.setSelection(structuredSelection);
	}

	private List<?> unwrapSelection() {
		List<Object> l = new ArrayList<Object>();
		if (getSelection() != null && !getSelection().isEmpty()
				&& getSelection() instanceof IStructuredSelection) {
			for (Iterator<?> iterator = ((IStructuredSelection) getSelection())
					.iterator(); iterator.hasNext();) {
				Object object = iterator.next();
				l.add(object);

			}

		}
		return l;

	}

	private ISelection getSelection() {
		return this.inernalProvider.getSelection();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.widgets.Control#setMenu(org.eclipse.swt.widgets.Menu)
	 */
	@Override
	public void setMenu(Menu menu) {
		if (label != null && !label.isDisposed())
			label.setMenu(menu);
		if (table != null && !table.isDisposed())
			table.setMenu(menu);

	}

	@Override
	public boolean setFocus() {
		if (table != null)
			return table.setFocus();
		return super.setFocus();
	}

	@Override
	public void addFocusListener(FocusListener listener) {
		table.addFocusListener(listener);
	}

	@Override
	public void removeFocusListener(FocusListener listener) {
		table.removeFocusListener(listener);
	}

	/**
	 * @param selection
	 */
	private void recalculateLabelText() {
//		StringBuffer buffy = new StringBuffer();
//		List<?> currSelection = unwrapSelection();
//		if (currSelection != null && !currSelection.isEmpty())
//			for (Iterator<?> iterator = currSelection.iterator(); iterator
//					.hasNext();) {
//				Object sel = iterator.next();
//				buffy.append(labelProvider.getText(sel));
//				if (iterator.hasNext())
//					buffy.append(", ");
//			}
//		label.setText(buffy.toString());
		List<?> currSelection = unwrapSelection();
		List<String> elements = new ArrayList<String>();
		if (currSelection != null && !currSelection.isEmpty()) {
			for (Iterator<?> iterator = currSelection.iterator(); iterator.hasNext();) {
				Object sel = iterator.next();
				elements.add(labelProvider.getText(sel));
			}
		}
		
		checkboxTableViewer.setInput(elements);
	}

	public Collection<?> getCurrentValue() {
		return currentValue;
	}

	class InternalSelectionProvider implements ISelectionProvider {

		public void setSelection(ISelection selection) {
			this.selection = selection;
			recalculateLabelText();
			if (!beQueit) {
				// notify
				// SelectionProviderMultipleSelectionObservableList$SelectionListener
				for (ISelectionChangedListener currListener : listeners) {
					currListener.selectionChanged(new SelectionChangedEvent(
							this, this.selection));
				}
			}
		}

		private java.util.List<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>();

		public void addSelectionChangedListener(
				ISelectionChangedListener listener) {
			listeners.add(listener);
		}

		public void removeSelectionChangedListener(
				ISelectionChangedListener listener) {
			listeners.remove(listener);
		}

		public ISelection getSelection() {
			return selection;
		}

		private ISelection selection;

	}

	public ISelectionProvider getInternalSelectionProvider() {
		return inernalProvider;
	}

	public void quietClearSelection() {
		beQueit = true;
		try {
			this.setSelection(new StructuredSelection());
		} finally {
			beQueit = false;
		}
	}
}
